package com.dms.modules.product.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dms.common.api.ApiResponse;
import com.dms.common.exception.BusinessException;
import com.dms.common.security.SecurityUtils;
import com.dms.modules.product.dto.ProductSkuDTO;
import com.dms.modules.product.entity.ProductSku;
import com.dms.modules.product.service.ProductSkuService;
import com.dms.modules.merchant.entity.Merchant;
import com.dms.modules.merchant.service.MerchantService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api/v1/product-skus")
@Api(tags = "商品SKU管理")
@Validated
public class ProductSkuController extends BaseProductController {

    @Autowired
    private ProductSkuService skuService;

    @Autowired
    private MerchantService merchantService;

    // ==================== 公共接口 ====================

    @GetMapping("/products/{productId}")
    @ApiOperation("获取商品的所有SKU")
    public ApiResponse<List<ProductSku>> getByProductId(
            @PathVariable @NotNull(message = "商品ID不能为空") Long productId) {
        return ApiResponse.success(skuService.getByProductId(productId));
    }

    @GetMapping("/check-code")
    @ApiOperation("检查SKU编码是否已存在")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<Boolean> checkSkuCode(
            @RequestParam @NotBlank(message = "SKU编码不能为空") String skuCode,
            @RequestParam(required = false) Long excludeId) {
        return ApiResponse.success(skuService.existsSkuCode(skuCode, excludeId));
    }

    @GetMapping("/products/{productId}/specs")
    @ApiOperation("根据规格获取SKU")
    public ApiResponse<ProductSku> getSkuBySpecs(
            @PathVariable @NotNull(message = "商品ID不能为空") Long productId,
            @RequestParam @NotBlank(message = "规格信息不能为空") String specs) {
        try {
            // 获取商品的所有SKU
            List<ProductSku> skuList = skuService.getByProductId(productId);
            if (skuList.isEmpty()) {
                return ApiResponse.error("商品暂无SKU信息");
            }

            // 查找匹配的SKU
            ProductSku matchedSku = skuList.stream()
                    .filter(sku -> {
                        String skuSpecs = sku.getSpecValues();
                        return skuSpecs != null && skuSpecs.equals(specs);
                    })
                    .findFirst()
                    .orElse(null);

            if (matchedSku == null) {
                return ApiResponse.error("未找到匹配的SKU");
            }

            return ApiResponse.success(matchedSku);
        } catch (Exception e) {
            log.error("获取SKU失败: productId={}, specs={}, error={}", productId, specs, e.getMessage());
            return ApiResponse.error("获取SKU失败");
        }
    }

    // ==================== 商家接口 ====================

    @GetMapping("/page")
    @ApiOperation("分页查询商家SKU列表")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<IPage<ProductSku>> pageMerchantSkus(
            @ApiParam("页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @ApiParam("每页大小") @RequestParam(defaultValue = "10") Integer pageSize,
            @ApiParam("商品ID") @RequestParam(required = false) Long productId,
            @ApiParam("SKU状态") @RequestParam(required = false) Integer status) {
        Long merchantId = getCurrentMerchantId();
        Page<ProductSku> page = new Page<>(pageNum, pageSize);
        return ApiResponse.success(skuService.pageMerchantSkus(page, merchantId, productId, status));
    }

    @PostMapping
    @ApiOperation("创建商品SKU")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<Boolean> createMerchantSku(@RequestBody @Valid ProductSkuDTO skuDTO) {
        // 获取当前商家ID
        Long userId = SecurityUtils.getCurrentUserId();
        Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getUserId, userId));
        if (merchant == null) {
            throw new BusinessException("未获取到商家信息");
        }
        skuDTO.setMerchantId(merchant.getId());
        return ApiResponse.success(skuService.createMerchantSku(skuDTO));
    }

    @PutMapping
    @ApiOperation("更新商品SKU")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<Boolean> updateMerchantSku(@RequestBody @Valid ProductSkuDTO skuDTO) {
        // 获取当前商家ID
        Long userId = SecurityUtils.getCurrentUserId();
        Merchant merchant = merchantService.getOne(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getUserId, userId));
        if (merchant == null) {
            throw new BusinessException("未获取到商家信息");
        }
        skuDTO.setMerchantId(merchant.getId());
        return ApiResponse.success(skuService.updateMerchantSku(skuDTO));
    }

    @PutMapping("/batch/prices")
    @ApiOperation("批量更新SKU价格")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<Boolean> updateMerchantPrices(
            @RequestBody @NotEmpty(message = "价格映射不能为空") Map<Long, BigDecimal> skuPriceMap) {
        return ApiResponse.success(skuService.updateMerchantPrices(getCurrentMerchantId(), skuPriceMap));
    }

    @PutMapping("/batch/stocks")
    @ApiOperation("批量更新SKU库存")
    @PreAuthorize("hasRole('MERCHANT')")
    public ApiResponse<Boolean> updateMerchantStocks(
            @RequestBody @NotEmpty(message = "库存映射不能为空") Map<Long, Integer> skuStockMap) {
        return ApiResponse.success(skuService.updateMerchantStocks(getCurrentMerchantId(), skuStockMap));
    }

    // ==================== 管理员接口 ====================

    @GetMapping("/admin/list")
    @ApiOperation("管理员查看SKU列表")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<IPage<ProductSku>> listSkus(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) Long productId,
            @RequestParam(required = false) Long merchantId,
            @RequestParam(required = false) Integer status) {
        Page<ProductSku> page = new Page<>(pageNum, pageSize);
        return ApiResponse.success(skuService.pageSkus(page, productId, merchantId, status));
    }

    @PutMapping("/admin/{id}/status")
    @ApiOperation("管理员更新SKU状态")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<Boolean> updateSkuStatus(
            @PathVariable @NotNull(message = "SKU ID不能为空") Long id,
            @RequestParam @NotNull(message = "状态不能为空") Boolean enabled) {
        return ApiResponse.success(skuService.updateSkuStatus(id, enabled));
    }

    @Data
    public static class BatchStatusUpdateRequest {
        @NotEmpty(message = "SKU ID列表不能为空")
        private List<Long> skuIds;
        
        @NotNull(message = "状态不能为空")
        private Boolean enabled;
    }

    @PutMapping("/admin/batch/status")
    @ApiOperation("管理员批量更新SKU状态")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<Boolean> batchUpdateSkuStatus(@RequestBody @Valid BatchStatusUpdateRequest request) {
        return ApiResponse.success(skuService.batchUpdateSkuStatus(request.getSkuIds(), request.getEnabled()));
    }

    @GetMapping("/{skuId}/check-stock")
    @ApiOperation("检查SKU库存")
    public ApiResponse<Boolean> checkSkuStock(
            @PathVariable @NotNull(message = "SKU ID不能为空") Long skuId,
            @RequestParam @Min(value = 1, message = "数量必须大于0") Integer quantity) {
        return ApiResponse.success(skuService.checkStock(skuId, quantity));
    }
} 